package com.example.clientend.utils;

import com.alibaba.fastjson.JSONObject;
import com.example.clientend.domain.ComputerInfo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.*;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 获取被控端状态信息的工具类
 */
@Component
public class InfoGetter {
    // 会话信息输出日志txt文件路径
    @Value("${path.serviceLogPath}")
    private String logPath;
    // 本机设备信息配置txt文件路径
    @Value("${path.deviceInfoPath}")
    private String deviceInfoPath;

    /**
     * 生成本机状态信息，通过SendAliveMsg定时任务发送存活信息到主控端
     * @return
     */
    public ComputerInfo getComputerInfo(){
        ComputerInfo computerInfo = new ComputerInfo();
        JSONObject deviceInfo = getDeviceInfo();
        computerInfo.setDeviceClientId((String) deviceInfo.get("deviceClientId"));
        computerInfo.setDeviceName((String) deviceInfo.get("deviceName"));
//        computerInfo.setMacAddress(getMacAddress());
//        computerInfo.setPublicIP(getPublicIP());
        computerInfo.setMsgTime(new Date());
        computerInfo.setStatus(getStatus());
        computerInfo.setHardDiskInfo(getHardDiskInfo());
        return computerInfo;
    }

    /**
     * 获取公网IP(已暂时停用)
     * @return 被控端的公网IP
     */
    private String getPublicIP(){
        String publicIP = "";
        try {
            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
            while (networkInterfaces.hasMoreElements()) {
                NetworkInterface networkInterface = networkInterfaces.nextElement();
                if (networkInterface.getName().startsWith("wlan")) {
                    Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();
                    while (inetAddresses.hasMoreElements()) {
                        InetAddress inetAddress = inetAddresses.nextElement();
                        if (!inetAddress.isLoopbackAddress() && inetAddress.isSiteLocalAddress()) {
//                            System.out.println("IP Address: " + inetAddress.getHostAddress());
                            publicIP = inetAddress.getHostAddress();
                        }
                    }
                }
            }
            return publicIP;
        } catch (SocketException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取无线网卡mac地址(已暂时停用)
     * @return 被控端的无线网卡mac地址
     */
    private String getMacAddress(){
        List<String> macAddressList = new ArrayList<>();
        try {
            Enumeration<NetworkInterface> enumeration = NetworkInterface.getNetworkInterfaces();
            while (enumeration.hasMoreElements()) {
                StringBuffer stringBuffer = new StringBuffer();
                NetworkInterface networkInterface = enumeration.nextElement();
                if (networkInterface != null && networkInterface.getName().startsWith("wlan")&&!networkInterface.getDisplayName().contains("Virtual")) {
                    byte[] bytes = networkInterface.getHardwareAddress();
                    if (bytes != null) {
                        for (int i = 0; i < bytes.length; i++) {
                            if (i != 0) {
                                stringBuffer.append("-");
                            }
                            int tmp = bytes[i] & 0xff; // 字节转换为整数
                            String str = Integer.toHexString(tmp);
                            if (str.length() == 1) {
                                stringBuffer.append("0" + str);
                            } else {
                                stringBuffer.append(str);
                            }
                        }
                        String mac = stringBuffer.toString().toUpperCase();
                        macAddressList.add(mac);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return macAddressList.stream().distinct().collect(Collectors.joining(";"));
    }

    /**
     * 获取当前时间
     * @return 被控端的当前时间
     */
    private String getCurrentTime(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String currentTime = sdf.format(new Date());
        return currentTime;
    }

    /**
     * 获取当前远控状态
     * @return 被控端的当前远控状态
     */
    private String getStatus(){
        boolean isLogin = !isLogEmpty();
        if (isLogin){
            // 2表示output.log非空，已注册服务并生成会话相关信息
            return "2";
        }else {
            // 1表示output.log为空，此时被控端未注册服务，未登录向日葵服务器
            return "1";
        }
    }

    /**
     * 获取磁盘信息
     * @return 被控端程序安装所在磁盘的信息
     */
    public String getHardDiskInfo(){
        /* 获取所有磁盘信息 */
//        List<String> hardDiskInfoList = new ArrayList<>();
//        // 获取所有磁盘的根目录
//        File[] roots = File.listRoots();
//
//        // 遍历所有根目录
//        for (File root : roots) {
//            // 获取磁盘空间信息，并换算成以GB为单位
//            long totalSpace = root.getTotalSpace()/1024/1024/1024;
//            long usableSpace = root.getUsableSpace()/1024/1024/1024;
//            // 磁盘名
//            String hardDiskName = root.getAbsolutePath().split(":")[0];
//
//            String hardDiskInfo = hardDiskName + "：总容量" + totalSpace + "GB,可用容量" + usableSpace + "GB";
//            hardDiskInfoList.add(hardDiskInfo);
//        }
//        return String.join("；",hardDiskInfoList);
        
        /* 获取程序安装盘的磁盘信息 */
        // 获取当前项目目录
        File file = new File(".");
        // 获取绝对路径
        String currentWorkingDir = file.getAbsolutePath();
        // 截取盘符名(C、D、E等等)
        String hardDiskName = currentWorkingDir.substring(0,1);
        // 截取盘符根目录(C:/、D:/、E:/等等)
        String hardDiscPath = currentWorkingDir.substring(0,3);
        File discFile = new File(hardDiscPath);
        // 获取总容量并转换为以GB为单位
        long totalSpace = discFile.getTotalSpace()/1024/1024/1024;
        // 获取可用容量并转换为以GB为单位
        long usableSpace = discFile.getUsableSpace()/1024/1024/1024;
        // 计算磁盘使用率
        double usedRatio = (double) (totalSpace - usableSpace) * 100 / totalSpace;
        // 保留两位小数
        String formattedNumber = String.format("%.2f", usedRatio);
        usedRatio = Double.parseDouble(formattedNumber);
        // 生成硬盘信息字符串
        String hardDiskInfo = "程序安装磁盘-" + hardDiskName + "盘：总容量" + totalSpace + "GB,可用容量" + usableSpace + "GB,已使用" + usedRatio + "%";
        return hardDiskInfo;
    }

    /**
     * 获取本机设备信息配置txt文件中的配置内容
     * @return
     */
    public JSONObject getDeviceInfo(){
        JSONObject deviceInfo = new JSONObject();
        try (BufferedReader reader = new BufferedReader(new FileReader(deviceInfoPath))) {
            String currentString;
            while ((currentString = reader.readLine()) != null) {
                // 每行配置信息的形式为 xxx：XXX
                // 使用":"作为分隔符分别截取出配置名称(xxx)和配置内容(XXX)
                String[] deviceInfoPair = currentString.split(":");
                // 若长度为2，说明该配置有填写具体的配置内容
                if (deviceInfoPair.length==2){
                    deviceInfo.put(deviceInfoPair[0],deviceInfoPair[1]);
                }
                // 若长度为1，说明该配置没有填写具体的配置内容，赋一个""防止解析时报错
                if (deviceInfoPair.length==1){
                    deviceInfo.put(deviceInfoPair[0],"");
                }
            }
            return deviceInfo;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 判断log文件中是否有会话信息生成
     * @return log文件是否为空
     */
    public boolean isLogEmpty(){
        File file = new File(logPath);
        try {
            BufferedReader reader = null;
            boolean isEmpty = true;
            try {
                reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
                while ((reader.readLine()) != null) {
                    isEmpty = false;
                    break;
                }
            } catch (IOException e) {
                e.printStackTrace();
                isEmpty = false;
            } finally {
                if (reader != null) {
                    reader.close();
                }
                return isEmpty;
            }
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    public boolean isStoppedButNotEmpty(){
        try (BufferedReader reader = new BufferedReader(new FileReader(logPath))) {
            int lineNum = 0;
            while(reader.readLine()!=null){
                lineNum++;
            }
            return lineNum == 1 || lineNum== 9;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }
}
